import { useInfiniteScroll } from "ahooks"
import { isPlainObject } from "lodash"

type BaseQueryParams = {
    page: number
    page_size: number
}

interface PaginationQuery extends BaseQueryParams {}

interface PaginationResponse<T> {
    d?: T[]
    list?: T[]
    t?: number
    s?: number
}

interface UsePaginatedListOptions<Q, T> {
    fetcher: (query: PaginationQuery) => Promise<PaginationResponse<T> | undefined>
    initialQuery?: Q
    pageSize?: number
    reloadDeps?: (number | string | null | undefined)[]
}

export function usePaginatedList<Q extends object = {}, T extends object = {}>({
    fetcher,
    initialQuery,
    pageSize = 15,
    reloadDeps = [],
}: UsePaginatedListOptions<Q, T>) {
    const { loading, loadMore, noMore, reload, data, loadingMore } = useInfiniteScroll(
        async (data) => {
            const currentPage = Math.floor((data?.list?.length || 0) / pageSize) + 1
            const query: PaginationQuery = {
                ...(isPlainObject(initialQuery) ? initialQuery : {}),
                page: currentPage,
                page_size: pageSize,
            }
            const res = await fetcher(query)
            const currentList = res && Array.isArray(res.d) ? res.d : []
            return {
                list: currentList,
                noMore: currentList.length < pageSize,
            }
        },
        {
            isNoMore: (d) => d?.noMore,
            reloadDeps,
        },
    )

    return {
        list: Array.isArray(data?.list) ? data.list : [],
        loading: loading || loadingMore,
        data,
        noMore,
        loadMore,
        reload,
    }
}
